package 创建型模式.单例模式.双检锁;

/**
 * @author 康米
 * {@code @date} 2023/2/1  17:37
 */
public class DoubleCheckedLocking {

    /**
     * 为了实现懒加载
     * <p>
     * 注意：添加 volatile 为了防止JVM指令重排
     * 不添加volatile依然能实现'相对线程安全'的单例模式
     * <p>
     * volatile：在读操作前，所有的写操作必须要完成
     * <p>
     * */
    private static volatile DoubleCheckedLocking doubleCheckedLocking;

    private DoubleCheckedLocking(){}

    /**
     * 用途：即实现懒加载，又防止直接加锁影响性能
     * @return 唯一实例
     */
    public static DoubleCheckedLocking getInstance(){
        //判断是否实例化
        if (doubleCheckedLocking==null){
            synchronized (DoubleCheckedLocking.class){
                //防止的情况：该类未完成初始化时
                //当线程A访问getInstance并且进行了加锁
                //且线程B同时访问了getInstance，且因为线程A的加锁导致被阻塞
                //第二次判空可以防止A释放锁后，线程B重复加锁
                if (doubleCheckedLocking==null){
                    doubleCheckedLocking=new DoubleCheckedLocking();
                }
            }
        }
        return doubleCheckedLocking;
    }

    /**
     * 该对象具体方法的实现
     */
    public void show(){
        System.out.println("单例模式-双检锁模式");
    }
}
